/**
 * Copyright (c) 2007,中企动力华南研发中心
 * All rights reserved.
 */

package com.ce.pms.authorization.filter;
import java.io.IOException;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.ce.pms.authorization.model.AuthorizedInfo;
import com.ce.pms.common.vo.OrganizationalStructureVO;
import com.ce.pms.login.web.LoginAction;
import com.ce.util.CurrentUserThread;
import com.ce.webframework.sec.util.InitPlugIn;
/**
 * 逻辑、功能相关描述:
 *权限相关，对所有访问服务器端的URL权限验证。
 * @author 刘科学  编写日期：2008-1-25
 * @author <a href="mailto:szyixianjian@myce.net.cn">易贤建</a>  修改日期：2008-01-25
 */

public class PmsRightLimitFilter implements Filter {

	WebApplicationContext applicationContext = null;
	public void init(FilterConfig filterConfig) {
		applicationContext = WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext());
	}
	/**
	 * 处理页面URL权限控制
	 *
	 * @param request
	 * @param response
	 * @param filterChain
	 */
	/**
	 * Function:
	 *
	 * @param
	 * @return Create author:刘科学 Create on:2008-1-25
	 * Edit author:易贤建 Edit on:2008-1-25 Why:修改不需要权限控制的URL放到配置文件配置。
	 */
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain filterChain) throws IOException, ServletException {

		HttpServletRequest servletRequest = (HttpServletRequest) request;
		HttpSession session = servletRequest.getSession();


		//获得页面地址，如:/ccms/LoginAction.do?
		String url = servletRequest.getRequestURI();

		String webapppath = servletRequest.getContextPath();


//		单点登陆删除 begin
		/*不进行权限控制的URL，类似登录页面之类是不需要进行权限控制的，
		 * 在i18n/pms/auth/authIgnore.properties中配置.
		 * 将不需要权限控制的URL直接跳过。
		 * url配置了，则返回一个相应的字符串。如果没配置，返回"".
		 */
		String temp = url.substring(url.lastIndexOf("/") + 1, url.length());
		String ignoreUrl = applicationContext.getMessage(temp, null,"", servletRequest.getLocale());
		if (!"".endsWith(ignoreUrl)) {
			filterChain.doFilter(request, response);
			return;
		}
		String islogin=(String)session.getAttribute(LoginAction.LOGIN_USER);
		if(islogin==null){
			forwardPage(request, response, "loginres.jsp");//删除单点登陆时删除
			return;
		}

//		单点登陆删除 end

		/*用户登录的时候会从统一用户组件获得用户名和密码。
		 * 这里将会从session中获得用户对象，并判断是否为空，如果为空，则证明该用户没有正常登录，程序将会跳转到错误页面提示用户登录*/
		OrganizationalStructureVO loginUser = (OrganizationalStructureVO) session.getAttribute(PmsAuthenticateFilter.LOGIN_USER_KEY);
		if (loginUser == null) {

			filterChain.doFilter(request, response);
			return;
		}else{
			CurrentUserThread.set(loginUser);
		}

		if (url.equalsIgnoreCase(webapppath+"/indexAction.do") || url.equals(webapppath+"/indexAction.do")){

			forwardPage(request, response, "indexAction.do?method=workTableDatas");
			filterChain.doFilter(request, response);
			return;
		}

		/*用户登录的时候会把权限系统的信息统一放到服务器缓存里。
		 * 这里程序会通过缓存获取该用户的权限信息并判断是否为空，如果为空，则证明该用户没有任何权限，程序将会跳转到错误页面提示用户*/
	//	LruCache lc = ResCache.getCacheInstance();//通过系统缓存获取该用户的权限信息

		//如果用户为注销动作,直接跳转到登录页面
		if (url.equalsIgnoreCase(webapppath+"/loginout.do")){
		//	lc.remove(loginUser);//清空权限缓存
			session.removeAttribute(PmsAuthenticateFilter.LOGIN_USER_KEY);
			session.removeAttribute(PmsAuthenticateFilter.LOGIN_USER_RIGHT_KEY);
			session.invalidate();//清空session
			loginUser = null;
//			forwardPage(request, response, "logout.jsp");//删除单点登陆时打开

			forwardPage(request, response, "loginres.jsp");//删除单点登陆时删除
			return;
		}

		AuthorizedInfo authInfo = (AuthorizedInfo) session.getAttribute(PmsAuthenticateFilter.LOGIN_USER_RIGHT_KEY);
		//如果该用户没有权限信息,那就不用比较了
		if (authInfo == null) {

			filterChain.doFilter(request, response);
			return;
		}

		/*接下来将读取URL并进行处理，例如：http://localhost/IndexAction.do?method=list&key=next转换成IndexAction.do?method=list*/
		String authURL = url.substring(url.lastIndexOf("/") + 1, url.length());//得到*.do参数，如：IndexAction.do
		String method = servletRequest.getParameter("method"); //获取method参数
		if (method != null) {
			authURL = authURL + "?method=" + method;
		}
		/*把当前用户访问URL与记录在权限系统的该用户拥有的权限URL进行比较，如果用户没有该URL的权限，则跳转到错误页面*/
		if (!verifyPageAuth(authInfo, authURL)) {
			forwardPage(request, response,"/ErrorAction.do?method=forwardErrorPage");
			return;
		}
		filterChain.doFilter(request, response);
	}

	/**
	 * Function:
	 * 跳转页面
	 * @param
	 * @return Create author:刘科学 Create on:2008-1-25
	 */
	private void forwardPage(ServletRequest request,
			ServletResponse response, String url) throws ServletException, IOException {
		HttpServletRequest servletRequest = (HttpServletRequest) request;
		servletRequest.getRequestDispatcher(url).forward(request, response);
	}


	/**
	 * Function:
	 * 验证该用户是否可以访问此URL
	 * @param auth 保存授权信息的对象
	 * @param authURL 当前要访问道页面
	 * @return Create author:刘科学 Create on:2008-1-25
	 */
	private boolean verifyPageAuth(AuthorizedInfo authInfo, String authURL) {
		boolean result = false;
		if (authInfo != null) {

			Map mapUrl=authInfo.getUrlMap();
			if(mapUrl.containsKey(authURL)){
				return true;
			}
			Map map=(Map)applicationContext.getServletContext().getAttribute(InitPlugIn.APPLICATION_ALL_AUTH);
			//Map map=authInfo.getAllMap();
			if(!map.containsKey(authURL)){
				return true;
			}

		}
		return result;
	}

	public void destroy() {

	}


}
